#pragma once

#include <linux/types.h>
#include <linux/page_types.h>
#include <linux/page-flags.h>
#include <linux/list_lru.h>
#include <linux/numa.h>

/* Reuses the bits in struct page */
typedef struct page slab_t;

#define slab_freelist(s) 0

#define OO_SHIFT 16
#define OO_MASK ((1 << OO_SHIFT) - 1)

/*
 * Word size structure that can be atomically updated or read and that
 * contains both the order and the number of objects that a slab of the
 * given order would contain.
 */
struct kmem_cache_order_objects
{
    unsigned int x;
};

/*
 * freeptr_t represents a SLUB freelist pointer, which might be encoded
 * and not dereferenceable if CONFIG_SLAB_FREELIST_HARDENED is enabled.
 */
typedef struct
{
    unsigned long v;
} freeptr_t;

/*
 * The slab lists for all objects.
 */
struct kmem_cache_node
{
};

struct kmem_cache
{
    const char *name;
    slab_flags_t flags;
    struct kmem_cache_order_objects oo;
    unsigned int offset; /* Free pointer offset */
    unsigned int size;
    unsigned int object_size;	/* Object size without metadata */
    unsigned int align;		/* Alignment */
    unsigned int inuse;		/* Offset to metadata */

    int refcount;			/* Refcount for slab cache destroy */

    void (*ctor)(void *object);	/* Object constructor */

    struct kmem_cache_node *node[MAX_NUMNODES];
};

struct kmalloc_info_struct
{
    const char *name[NR_KMALLOC_TYPES];
    unsigned int size;
};

struct kmem_cache *kmalloc_slab(size_t size, kmem_buckets *b, gfp_t flags, unsigned long caller);

/*
 * Kmalloc array related definitions
 */

/*
 * SLUB directly allocates requests fitting in to an order-1 page
 * (PAGE_SIZE*2).  Larger requests are passed to the page allocator.
 */
#define KMALLOC_SHIFT_HIGH	(PAGE_SHIFT + 1)
#define KMALLOC_SHIFT_MAX	(MAX_PAGE_ORDER + PAGE_SHIFT)
#ifndef KMALLOC_SHIFT_LOW
#define KMALLOC_SHIFT_LOW	3
#endif

/*
 * Kmalloc subsystem.
 */
#ifndef KMALLOC_MIN_SIZE
#define KMALLOC_MIN_SIZE (1 << KMALLOC_SHIFT_LOW)
#endif
